package com.squareup.moshi;

import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;

public class DefaultNullSafeJsonAdapter<T> extends JsonAdapter<T> {

    private final JsonAdapter<T> delegate;

    public DefaultNullSafeJsonAdapter(JsonAdapter<T> delegate) {
        this.delegate = delegate;
    }

    public JsonAdapter<T> delegate() {
        return delegate;
    }

    @SuppressWarnings("unchecked")
    @Override
    public @Nullable
    T fromJson(JsonReader reader) throws IOException {
        if (reader.peek() == JsonReader.Token.NULL) {
            try {
                ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
                if (type != null) {
                    Class clazz = (Class<T>) type.getActualTypeArguments()[0];
                    return (T) clazz.newInstance();
                } else {
                    return reader.nextNull();
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
            return reader.nextNull();
        } else {
            return delegate.fromJson(reader);
        }
    }

    @Override
    public void toJson(JsonWriter writer, @Nullable T value) throws IOException {
        if (value == null) {
            writer.nullValue();
        } else {
            delegate.toJson(writer, value);
        }
    }

    @Override
    public String toString() {
        return delegate + ".nullSafe()";
    }

}
